package com.ruoyi.common.utils;

import com.alibaba.fastjson2.JSON;  // 更新为 FastJSON 2.x
import com.alibaba.fastjson2.TypeReference;  // 更新为 FastJSON 2.x
import com.alibaba.fastjson2.JSONWriter;  // 更新为 FastJSON 2.x
import com.ruoyi.common.core.domain.JsonFieldConstants;
import com.ruoyi.common.core.domain.MemberCarConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.*;

/**
 * 停车场API调用工具类
 */
@Component
public class ParkingApiUtil {

    private static final Logger log = LoggerFactory.getLogger(ParkingApiUtil.class);

//    测试参数

//    private static final String SEND_URL = "https://syx-open.jslife.com.cn/openApi";
//    private static final String APP_ID = "989841413043769345";
//    private static final String PROJECT_CODE = "0020200529";
//    private static final String ABILITY_CODE = "API-CXYEJC";
//    private static final String PRIVATE_KEY = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKtNXQet9kUZKt3SwBNcC0ZK3exeAwrFXwy6MwWI/ws0jDtx08LGh78ydoQ5VMw8MudZ5mnzXQtkFr1Zmj0M5z9bz8f5Td1S+zjPFuJSvHa54IajgQD+nPMjl7d9IgBJrYFvMdOojs6voxibzGv/zPMFSZJZmtdoLsYg6gnV2QTpAgMBAAECgYAHu/t6UElxPzynPU+80AgWSWURugDrKJQtD+8jzdauG9ZFDNOh1LLmWBHv0GLawdEOjwmPORS3YfKA5B3Jqd568+ts0a45fXIfzcJtxmUwMSVeEwmLVIKEFWE14xSEKYt/iVH08Qgdi5WDSMvmlQmOonV6DvFblE7U0Uro3w22/QJBANzTtoEpitkcxozrfWNozTvfFrxJFUgVCp9zuxjaBgLPj/MRvvEAOUxYox6gt70pbNsDAgMVrWpg4vonUAM8gkMCQQDGlkMIno3atqCkFc49Xf4/qnhCnK4FyugXtgBYpzXhf/ruSIwyOzgQOxIOPdb1XkDdWoETLMlLuCk36hOK7PdjAkB1Ll+FcN7+UTfHZdtW2jE2WS6+YWXKp2fIr2gUSvWvnic8DCmvx7egHNUKlqyJ06axHYp+yo0IiztHFX9vCDfzAkEApgD2CD6CVlJT9tZDkQkBgDcAUK6oyi7T1P5PS8x7PgW9vXLnvxXBx8+ZSE5pYrNnhaIiQ+UsYB+SVStXKsrsAQJATyWKNa/Rd55Q7zFV35XWNoTSzPnu3nvb+9rF8m22NKXwyRlPVt8CX8+QaTOFmdbkN8n5NHIxR0rbLEnDupp0ow==";
//    private static final String CID = "880075500000002";


//    正式参数

    private static final String SEND_URL = "https://jsopen.jslife.com.cn/openApi";
    private static final String APP_ID = "1204424499710160897";
    private static final String PROJECT_CODE = "p240199697";
    private static final String ABILITY_CODE = "kfpt_syfw";
    private static final String PRIVATE_KEY ="MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAKSQ3Aija433QwO9THf2aaAtKc7Zj8lWkNdeGMaEeZymTvqzuO4j50lyRWxZWIxR+HHjzD6cDOGUyiY8wyK6lSAuL5v+Qysvo5HCiwo79taDXqv4xihGp/cljGj2gh8/uM3T8eA16t74M0CbOYgaVkFIZc4LNGXfA+qUV9bI9n/rAgMBAAECgYBP+BDkpb0zTK+lFo0dUoH7k1bYrMKBnW5fKduyRFfwdqS0kTdRieLvvvbbcwNjlMW9Wmw7FIvx5uLg9+//ZVnndGAYN+22mdIWrKrbA5siAK2y4zyZ6dJ0ZwrLT467sfIWqs33AKaxbtxPl7Ps0VfrM9Zutw2RkBUc5tDBn3cqcQJBAN0mQs+lD2ZycChcYfZ1i6e81PUJ7sCsqGhVw0b9CY1EV1/GE2hnMRepvwgSkRJiEyjDCm9SFAmx28k4DtiD1BMCQQC+f97L+HK/2o+29rAxlao6OQvcGhJ8PoHPs0WyI9mOXTXsDystVb82KBOiDzDuBBNn4VCTNVPeq/3t7N6+FK/JAkBgHRfebQtzZ/ss33HIDrBCl4Qqd0WnwaJzrgpv2NuE5RXgTxLyRh8E/MZEuOUKC0vuZE4tsYt55y3xlwaEvU63AkBVhnURX/6skcR54TDjYg0lzJy9eVsZOrru885zltLCrqhZzcmVtex9tOpzlJxkD6Jive592LBJxS/g1Lp/3iu5AkAuYkKQJTq6jlJT7wchAyAhwiy4DiKscH0Gy/mP/6OUHAhdJqcFkxQOvB4l2hi9zSSuRPkkAlxdYG5RabBXT14M";
    private static final String CID = "000000008088289";

    /**
     * 查询车辆信息
     * 根据车牌号，是否是会员车辆
     */
    public Map<String, Object> getCarinfo(String carNo) {
        String interfaceName = "3c.pay.createorderbycarno";
        Map<String, Object> apiParam = buildApiParam(interfaceName, carNo);
        String sign = generateSign(apiParam);
        apiParam.put("sign", sign);

        String content = sendPostRequest(apiParam);
        System.out.println(content);
        log.info("发送请求: {}", content);
        return processResponse(content, "getCarinfo");
    }

    /**
     * 缴费操作--支付结果通知
     */
    public Map<String, Object> addChargeInfo(String carNo, String orderNo) {
        String interfaceName = "3c.pay.notifyorderresult";
        Map<String, Object> carInfo = getCarinfo(carNo);
        String orderOut = "test";
        Map<String, Object> apiParam = buildChargeApiParam(interfaceName, carNo, orderNo,orderOut, carInfo);
        String sign = generateSign(apiParam);
        apiParam.put("sign", sign);

        String content = sendPostRequest(apiParam);
        return processResponse(content, "addChargeInfo");
    }

    /**
     * 时长减免
     * 3c.order.discount
     * 车牌打折接口
     *
     * 描述: 使用车牌号码对场内车进行减免，月卡车、白名单也会返回打折成功，车辆未入场打折失败。
     *
     * 参数params:JSON格式字符串
     *
     * 接口编码：3c.order.discount
     *
     */
    public Map<String, Object> addMemberRelief(String carNo, String parkCode, Integer freeTime) {
        String interfaceName = "3c.order.discount";
//        把分钟变成小时
        // 将分钟转换为小时（向下取整，如120分钟=2小时）

        Integer freeHours = freeTime / 60;
        // 向上取整（根据业务需求选择）
//        if (freeTime % 60 != 0) {
//            freeHours += 1;
//        }


        Map<String, Object> apiParam = buildDiscountApiParam(interfaceName, carNo,parkCode, freeHours, 1);


        String sign = generateSign(apiParam);
        apiParam.put("sign", sign);

        String content = sendPostRequest(apiParam);
        Map<String, Object> result = processResponse(content, "addMemberRelief");
        log.info("时长减免处理结果: resCode={}, resMsg={}",
                result.get("resCode"), result.get("resMsg"));

        return result;
    }


    /**
     * 时长减免
     * 3c.order.discount
     * 车牌打折接口
     *
     * 描述: 让车辆出场，全免
     *
     * 参数params:JSON格式字符串
     *
     * 接口编码：3c.order.discount
     *
     */
    public Map<String, Object> freeCharge(String carNo, String parkCode) {
        String interfaceName = "3c.order.discount";

        Map<String, Object> apiParam = buildDiscountApiParam(interfaceName, carNo,parkCode, 1, 2);


        String sign = generateSign(apiParam);
        apiParam.put("sign", sign);

        String content = sendPostRequest(apiParam);
        Map<String, Object> result = processResponse(content, "freeCharge");
        log.info("全免处理结果: resCode={}, resMsg={}",
                result.get("resCode"), result.get("resMsg"));

        return result;
    }




    /**
     * 减免
     */
    public Map<String, Object> addMemberReliefSh(String carNumber, String parkCode, Double amount) {
        String interfaceName = "3c.order.discount";
        Map<String, Object> apiParam = buildDiscountApiParam(interfaceName, carNumber, parkCode, amount.intValue(), 2);
        String sign = generateSign(apiParam);
        apiParam.put("sign", sign);

        String content = sendPostRequest(apiParam);
        return processResponse(content, "addMemberReliefSh");
    }

    /**
     * 发送POST请求（通用方法，支持指定URL、参数和响应类型）
     * @param url 请求URL
     * @param params 请求参数（Map类型）
     * @param responseType 响应类型（如 Map.class）
     * @return 响应结果
     */
    public <T> T postForObject(String url, Map<String, Object> params, Class<T> responseType) {
        log.info("调用API: {}", url);
        log.debug("请求参数: {}", params);

        // 添加通用参数
        params.put("app_id", APP_ID);
        params.put("timestamp", System.currentTimeMillis());

        // 生成签名
        String sign = generateSign(params);
        params.put("sign", sign);

        // 发送请求并获取响应内容
        String content = sendPostRequest(url, params);

        // 处理响应并转换为指定类型
        return processResponse(content, responseType);
    }

    /**
     * 发送POST请求到指定URL（支持自定义URL和参数）
     */
    private String sendPostRequest(String url, Map<String, Object> params) {
        try {
            URL targetUrl = new URL(url);
            HttpURLConnection conn = (HttpURLConnection) targetUrl.openConnection();
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");
            conn.setDoOutput(true);
            conn.setConnectTimeout(10000);
            conn.setReadTimeout(10000);

            String jsonParams = JSON.toJSONString(params, JSONWriter.Feature.WriteMapNullValue);
            try (OutputStream os = conn.getOutputStream()) {
                os.write(jsonParams.getBytes(StandardCharsets.UTF_8));
            }

            int responseCode = conn.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                try (BufferedReader br = new BufferedReader(
                        new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8))) {
                    StringBuilder response = new StringBuilder();
                    String line;
                    while ((line = br.readLine()) != null) {
                        response.append(line);
                    }
                    return response.toString();
                }
            } else {
                try (BufferedReader br = new BufferedReader(
                        new InputStreamReader(conn.getErrorStream(), StandardCharsets.UTF_8))) {
                    StringBuilder response = new StringBuilder();
                    String line;
                    while ((line = br.readLine()) != null) {
                        response.append(line);
                    }
                    log.error("HTTP请求失败，状态码: {}, 响应: {}", responseCode, response.toString());
                    return null;
                }
            }
        } catch (IOException e) {
            log.error("HTTP请求异常", e);
            return null;
        }
    }

    /**
     * 处理响应结果并转换为指定类型
     */
    private <T> T processResponse(String content, Class<T> responseType) {
        if (content == null) {
            return null;
        }

        try {
            if (responseType == String.class) {
                return (T) content;
            }
            // 转换为Map或其他类型
            return JSON.parseObject(content, responseType);
        } catch (Exception e) {
            log.error("解析响应失败: {}", e.getMessage());
            return null;
        }
    }

    /**
     * 构建基础API参数（查询车辆信息）
     */
    private Map<String, Object> buildApiParam(String interfaceName, String carNo) {
        Map<String, Object> bizContent = new HashMap<>();
        Map<String, Object> pMap = new HashMap<>();
        Map<String, Object> attributes = new HashMap<>();

        attributes.put("businesserCode", CID);
        attributes.put("parkCode", PROJECT_CODE);
        attributes.put("orderType", "VNP");
        attributes.put("carNo", carNo);

        pMap.put("serviceId", interfaceName);
        pMap.put("requestType", "DATA");
        pMap.put("attributes", attributes);

        bizContent.put("p", pMap);
        bizContent.put("v", "2");
        bizContent.put("cid", CID);

        return buildBaseParam(interfaceName, bizContent);
    }

    /**
     * 构建缴费API参数
     */
    private Map<String, Object> buildChargeApiParam(String interfaceName, String carNo, String orderNo, String orderOut, Map<String, Object> carInfo) {
        Map<String, Object> bizContent = new HashMap<>();
        Map<String, Object> pMap = new HashMap<>();
        Map<String, Object> attributes = new HashMap<>();

        attributes.put("orderNo", orderNo);
        attributes.put("tradeStatus", "0");
        attributes.put("isCallBack", "0");
        attributes.put("payType", "WX");
        attributes.put("payTypeName", "微信");
        attributes.put("payTime", formatDate(new Date()));
        // 支付方流水号,订单在支付平台的流水号，如微信，支付宝，捷顺金科的流水号, （清分必传）
//        attributes.put("transactionId", orderOut);

        pMap.put("serviceId", interfaceName);
        pMap.put("requestType", "DATA");
        pMap.put("attributes", attributes);

        bizContent.put("p", pMap);
        bizContent.put("v", "2");
        bizContent.put("cid", CID);

        return buildBaseParam(interfaceName, bizContent);
    }

    /**
     * 构建减免API参数
     *     private Map<String, Object> buildDiscountApiParam(String interfaceName, String carNo, String ticketId, int value, int type) {
     *         Map<String, Object> bizContent = new HashMap<>();
     *         Map<String, Object> pMap = new HashMap<>();
     *         Map<String, Object> attributes = new HashMap<>();
     *
     *         attributes.put("carNo", carNo);
     *         attributes.put("parkCode", PROJECT_CODE);
     *         attributes.put("couponType", type);     // 1=时长减免，2=金额减免
     *         attributes.put("couponValue", value);   // 减免值（分钟或金额）
     *         attributes.put("couponId", ticketId);   // 新增：减免券ID
     *         attributes.put("isRepeat", 1);          // 是否可重复使用
     *
     *         pMap.put("serviceId", interfaceName);
     *         pMap.put("requestType", "DATA");
     *         pMap.put("attributes", attributes);
     *
     *         bizContent.put("p", pMap);
     *         bizContent.put("v", "2");
     *         bizContent.put("cid", CID);
     *
     *         return buildBaseParam(interfaceName, bizContent);
     *     }
     */

    /**
     * 构建.车牌打折接口的参数
     */
    private Map<String, Object> buildDiscountApiParam(String interfaceName, String carNo, String parkCode, int value, int type) {
        Map<String, Object> bizContent = new HashMap<>();
        Map<String, Object> pMap = new HashMap<>();
        Map<String, Object> attributes = new HashMap<>();

        attributes.put("carNo", carNo);
        attributes.put("parkCode", parkCode);

        // 优惠类型，0：减免金额，1：减免时间，2：全免
        attributes.put("couponType", type);
        // 减免值（小时或金额）
        attributes.put("couponValue", value);
        // 是否可重复使用
        attributes.put("isRepeat", 1);

        pMap.put("serviceId", interfaceName);
        pMap.put("requestType", "DATA");
        pMap.put("attributes", attributes);

        bizContent.put("p", pMap);
        bizContent.put("v", "2");
        bizContent.put("cid", CID);

        return buildBaseParam(interfaceName, bizContent);
    }

    /**
     * 构建公共基础参数
     */
    private Map<String, Object> buildBaseParam(String interfaceName, Map<String, Object> bizContent) {
        Map<String, Object> params = new TreeMap<>();
        params.put("app_id", APP_ID);
        params.put("projectCode", PROJECT_CODE);
        params.put("abilityCode", ABILITY_CODE);
        params.put("method", interfaceName);
        params.put("charset", "utf-8");
        params.put("format", "form");
        params.put("sign_type", "md5");
        params.put("timestamp", System.currentTimeMillis());
        params.put("biz_content", bizContent);
        return params;
    }

    /**
     * 发送POST请求
     */
    private String sendPostRequest(Map<String, Object> params) {
        try {
            URL url = new URL(SEND_URL);
            log.info("发送请求时，调用URL: {}", url);

            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");
            conn.setDoOutput(true);
            conn.setConnectTimeout(10000);
            conn.setReadTimeout(10000);

            String jsonParams = JSON.toJSONString(params, JSONWriter.Feature.WriteMapNullValue);
            try (OutputStream os = conn.getOutputStream()) {
                os.write(jsonParams.getBytes(StandardCharsets.UTF_8));
            }

            int responseCode = conn.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                try (BufferedReader br = new BufferedReader(
                        new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8))) {
                    StringBuilder response = new StringBuilder();
                    String line;
                    while ((line = br.readLine()) != null) {
                        response.append(line);
                    }
                    return response.toString();
                }
            } else {
                try (BufferedReader br = new BufferedReader(
                        new InputStreamReader(conn.getErrorStream(), StandardCharsets.UTF_8))) {
                    StringBuilder response = new StringBuilder();
                    String line;
                    while ((line = br.readLine()) != null) {
                        response.append(line);
                    }
                    log.error("HTTP请求失败，状态码: {}, 响应: {}", responseCode, response.toString());
                    return null;
                }
            }
        } catch (IOException e) {
            log.error("HTTP请求异常", e);
            return null;
        }
    }

    /**
     * 处理响应结果
     */
    private Map<String, Object> processResponse(String content, String method) {
        Map<String, Object> result = new HashMap<>();
        if (content == null) {
            result.put("resCode", 1);
            result.put("resMsg", "接口连接出错");
            return result;
        }
        String code = JsonFieldConstants.CODE;
        String resultCode = JsonFieldConstants.RESULTCODE;

        try {
            Map<String, Object> jsonResult = JSON.parseObject(content, new TypeReference<Map<String, Object>>() {});
            log.info("{} 接口响应: {}", method, jsonResult);

            result.put("jsonResult", jsonResult);

//            if (jsonResult.containsKey("code") && MemberCarConstants.JSON_CODE.equals(jsonResult.get("code"))) {
            if (jsonResult.containsKey(code) && MemberCarConstants.JSON_CODE.equals(jsonResult.get(code))) {

                Map<String, Object> bizResponse = (Map<String, Object>) jsonResult.get("biz_response");
                if (bizResponse != null && MemberCarConstants.SUCCESS_CODE_STRING.equals(String.valueOf(bizResponse.get(resultCode)))) {
                    result.put("resCode", 0);
                    result.put("data", bizResponse.get("dataItems"));

                    result.put("resMsg", "操作成功");
                    return result;
                }
                result.put("resCode", bizResponse != null ? bizResponse.getOrDefault("resultCode", 1) : 1);
                result.put("resMsg", bizResponse != null ? bizResponse.getOrDefault("message", "业务处理失败") : "业务响应为空");
            } else {
                result.put("resCode", jsonResult.getOrDefault("resultCode", jsonResult.getOrDefault("code", 1)));
                result.put("resMsg", jsonResult.getOrDefault("message", "接口返回错误"));
            }
        } catch (Exception e) {
            log.error("解析响应失败", e);
            result.put("resCode", 1);
            result.put("resMsg", "解析响应失败: " + e.getMessage());
        }
        return result;
    }

    /**
     * 生成签名
     */
    private String generateSign(Map<String, Object> params) {
        List<String> keys = new ArrayList<>(params.keySet());
        Collections.sort(keys);

        StringBuilder signBuilder = new StringBuilder();
        for (String key : keys) {
            if ("sign".equals(key)) continue;
            Object value = params.get(key);
            signBuilder.append("&").append(key).append("=").append(encodeValue(value));
        }
        String signData = signBuilder.substring(1);

        try {
            PrivateKey privateKey = getPrivateKey(PRIVATE_KEY);
            Signature signature = Signature.getInstance("MD5withRSA");
            signature.initSign(privateKey);
            signature.update(signData.getBytes(StandardCharsets.UTF_8));
            byte[] signedBytes = signature.sign();
            return Base64.getEncoder().encodeToString(signedBytes);
        } catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException | InvalidKeySpecException e) {
            log.error("签名生成失败", e);
            throw new RuntimeException("签名生成失败", e);
        }
    }

    /**
     * 编码参数值
     */
    private String encodeValue(Object value) {
        if (value instanceof Map || value instanceof List) {
            return JSON.toJSONString(value, JSONWriter.Feature.WriteMapNullValue);
        }
        return value != null ? value.toString() : "";
    }

    /**
     * 从PEM格式字符串获取私钥
     */
    private PrivateKey getPrivateKey(String privateKeyPem) throws NoSuchAlgorithmException, InvalidKeySpecException {
        String privateKeyStr = privateKeyPem
                .replace("-----BEGIN RSA PRIVATE KEY-----", "")
                .replace("-----END RSA PRIVATE KEY-----", "")
                .replaceAll("\\s+", "");

        byte[] keyBytes = Base64.getDecoder().decode(privateKeyStr);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        return keyFactory.generatePrivate(keySpec);
    }

    /**
     * 格式化日期
     */
    private String formatDate(Date date) {
        java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(date);
    }
}
